﻿using System;
using System.IO;
using Mars.Event;
using Mars.GameCore;
using Mars.Module;
using UnityEngine;

namespace Mars.Network
{
    /// <summary>
    /// 默认网络通道帮助
    /// </summary>
    public class DefaultNetworkChannelHelper : INetworkChannelHelper
    {
         private INetworkChannel m_NetworkChannel;
         private IEventManager m_EventManager;

        public DefaultNetworkChannelHelper()
        {
            m_NetworkChannel = null;
            m_EventManager = null;
        }

        public void Initialize(INetworkChannel netChannel)
        {
            m_EventManager = ModuleManager.GetModule<EventManager>();
            m_NetworkChannel = netChannel;
            m_NetworkChannel.RegisterHandler(new DefaultPacketReceiveHeaderHandler());
            m_NetworkChannel.RegisterHandler(new DefaultPacketReceiveBodyHandler());
            m_NetworkChannel.RegisterHandler(new DefaultPacketSendHeaderHandler());
            m_NetworkChannel.RegisterHandler(new DefaultPacketSendBodyHandler());
            m_NetworkChannel.RegisterHeartBeatHandler(new DefaultPacketHeartBeatHandler());
            m_NetworkChannel.RegisterMessageCompressHandler(new DefaultMessageCompressHandler());
            m_NetworkChannel.RegisterMessageDecompressHandler(new DefaultMessageDecompressHandler());

            m_EventManager.CheckSubscribe(NetworkConnectedEventArgs.EventId, OnNetworkConnectedEventArgs);
            m_EventManager.CheckSubscribe(NetworkClosedEventArgs.EventId, OnNetworkClosedEventArgs);
            m_EventManager.CheckSubscribe(NetworkMissHeartBeatEventArgs.EventId, OnNetworkMissHeartBeatEventArgs);
            m_EventManager.CheckSubscribe(NetworkErrorEventArgs.EventId, OnNetworkErrorEventArgs);
        }

        public void Shutdown()
        {
            m_EventManager.Unsubscribe(NetworkConnectedEventArgs.EventId, OnNetworkConnectedEventArgs);
            m_EventManager.Unsubscribe(NetworkClosedEventArgs.EventId, OnNetworkClosedEventArgs);
            m_EventManager.Unsubscribe(NetworkMissHeartBeatEventArgs.EventId, OnNetworkMissHeartBeatEventArgs);
            m_EventManager.Unsubscribe(NetworkErrorEventArgs.EventId, OnNetworkErrorEventArgs);
            m_NetworkChannel = null;
        }

        public void PrepareForConnecting()
        {
            m_NetworkChannel.Socket.ReceiveBufferSize = 1024 * 64 - 1;
            m_NetworkChannel.Socket.SendBufferSize = 1024 * 64 - 1;
        }

        public bool SendHeartBeat()
        {
            var message = m_NetworkChannel.PacketHeartBeatHandler.Handler();
            m_NetworkChannel.Send(message);
            return true;
        }

        public bool SerializePacketHeader<T>(T messageObject, MemoryStream destination, out byte[] messageBodyBuffer) where T : MessageObject
        {
            return m_NetworkChannel.PacketSendHeaderHandler.Handler(messageObject, m_NetworkChannel.MessageCompressHandler, destination, out messageBodyBuffer);
        }

        public bool SerializePacketBody(byte[] messageBodyBuffer, MemoryStream destination)
        {
            return m_NetworkChannel.PacketSendBodyHandler.Handler(messageBodyBuffer, destination);
        }

        public bool DeserializePacketHeader(byte[] source)
        {
            return m_NetworkChannel.PacketReceiveHeaderHandler.Handler(source);
        }

        public bool DeserializePacketBody(byte[] source, int messageId, out MessageObject messageObject)
        {
            return m_NetworkChannel.PacketReceiveBodyHandler.Handler(source, messageId, out messageObject);
        }

        public void Clear()
        {
            m_NetworkChannel?.Close();
            m_NetworkChannel = null;
        }

        private void OnNetworkConnectedEventArgs(object sender, BaseEventArgs e)
        {
            if (!(e is NetworkConnectedEventArgs ne) || ne.NetworkChannel != m_NetworkChannel)
            {
                return;
            }

            Debug.Log($"网络连接成功......{ne.NetworkChannel.Name}");
        }

        private void OnNetworkClosedEventArgs(object sender, BaseEventArgs e)
        {
            if (!(e is NetworkClosedEventArgs ne) || ne.NetworkChannel != m_NetworkChannel)
            {
                return;
            }

            Debug.Log($"网络连接关闭......{ne.NetworkChannel.Name}");
        }

        private void OnNetworkMissHeartBeatEventArgs(object sender, BaseEventArgs e)
        {
            if (!(e is NetworkMissHeartBeatEventArgs ne) || ne.NetworkChannel != m_NetworkChannel)
            {
                return;
            }

            Debug.LogWarning($"Network channel '{ne.NetworkChannel.Name}' miss heart beat '{ne.MissCount}' times.");
        }

        private void OnNetworkErrorEventArgs(object sender, BaseEventArgs e)
        {
            if (!(e is NetworkErrorEventArgs ne) || ne.NetworkChannel != m_NetworkChannel)
            {
                return;
            }

            Debug.LogError($"Network channel '{ne.NetworkChannel.Name}' error, error code is '{ne.ErrorCode}', error message is '{ne.ErrorMessage}'.");
            ne.NetworkChannel.Close();
        }
    }
}